package com.igoal.dto;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.igoal.entity.Category;
import com.igoal.entity.Hobby;
import com.igoal.entity.User;
import com.igoal.entity.UserInfo;
import com.igoal.entity.UserStatus;
import com.igoal.utils.StringUtils;
import com.igoal.utils.SynchronizeAttributeWithOther;
import com.igoal.utils.SynchronizeDirection;
import com.igoal.web.Constants;

public class UserDTO extends BaseDTO<User> implements Serializable {
	private static final long serialVersionUID = 7729568212231749855L;

	private String username;
	private String password;
	private String email; // required; unique
	// private Date updateDate;
	private String avatar;
	private String status;
	private Integer numberFriends;
	private Integer numberGoals;
	private Integer numberFollowed;
	private Integer numberFollows;
	private boolean male;
	private boolean enabled;
	private boolean accountLocked;
	private Date birthday;
	private String firstName;
	private String middleName;
	private String lastName;
	private String mobilePhone;
	private String phone;
	private String address;
	private String city;
	private String yahoo;
	private String google;
	private String skype;
	private String website;
	private int day;
	private int month;
	private int year;
	private boolean isLoggined;
	private String aboutMe;
	private Long[] categoryIds;
	
	private Map<String, Set<String>> hobbies = new HashMap<String, Set<String>>();

	public String getAboutMe() {
		return aboutMe;
	}

	public void setAboutMe(String aboutMe) {
		this.aboutMe = aboutMe;
	}

	public boolean isLoggined() {
		return isLoggined;
	}

	public void setLoggined(boolean isLoggined) {
		this.isLoggined = isLoggined;
	}

	public int getDay() {
		return day;
	}

	public void setDay(int day) {
		this.day = day;
	}

	public int getMonth() {
		return month;
	}

	public void setMonth(int month) {
		this.month = month;
	}

	public int getYear() {
		return year;
	}

	public void setYear(int year) {
		this.year = year;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getDisplayEmail() {
		if (this.email == null)
			return null;

		String demail = this.email;
		if (demail.length() > Constants.UI_EMAIL_CHARS) {
			demail = demail.substring(0, Constants.UI_EMAIL_CHARS - 3);
			demail += "...";
		}
		return demail;
	}

	public String getAvatar() {
		return avatar;
	}

	public void setAvatar(String avatar) {
		this.avatar = avatar;
	}

	public Integer getNumberFriends() {
		return numberFriends;
	}

	public void setNumberFriends(Integer numberFriends) {
		this.numberFriends = numberFriends;
	}

	public Integer getNumberGoals() {
		return numberGoals;
	}

	public void setNumberGoals(Integer numberGoals) {
		this.numberGoals = numberGoals;
	}

	public Integer getNumberFollowed() {
		return numberFollowed;
	}

	public void setNumberFollowed(Integer numberFollowed) {
		this.numberFollowed = numberFollowed;
	}

	public Integer getNumberFollows() {
		return numberFollows;
	}

	public void setNumberFollows(Integer numberFollows) {
		this.numberFollows = numberFollows;
	}

	public boolean isMale() {
		return male;
	}

	public void setMale(boolean male) {
		this.male = male;
	}

	public void setGender(boolean isMale) {
		this.male = isMale;
	}

	public boolean isEnabled() {
		return enabled;
	}

	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

	public boolean isAccountLocked() {
		return accountLocked;
	}

	public void setAccountLocked(boolean accountLocked) {
		this.accountLocked = accountLocked;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getMiddleName() {
		return middleName;
	}

	public void setMiddleName(String middleName) {
		this.middleName = middleName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getMobilePhone() {
		return mobilePhone;
	}

	public void setMobilePhone(String mobilePhone) {
		this.mobilePhone = mobilePhone;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getDisplayName() {
		String tmpLN = lastName == null ? "" : lastName;
		String tmpFN = firstName == null ? "" : firstName;
		String displayName = tmpLN + " " + tmpFN;
		if (displayName.trim().equals("")) {
			displayName = StringUtils.getEmailAddressPrefix(email);
			if (displayName == null) {
				displayName = "---";
			}
		}
		if (displayName.length() > Constants.UI_USERNMAE_CHARS) {
			displayName = displayName.substring(0,
					Constants.UI_USERNMAE_CHARS);
			displayName += "...";
		}
		return displayName;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	public String getYahoo() {
		return this.yahoo;
	}

	public void setYahoo(String yahoo) {
		this.yahoo = yahoo;
	}

	public String getGoogle() {
		return this.google;
	}

	public void setGoogle(String google) {
		this.google = google;
	}

	public String getSkype() {
		return this.skype;
	}

	public void setSkype(String skype) {
		this.skype = skype;
	}
	
	public Map<String, Set<String>> getHobbies() {
		return hobbies;
	}

	public void setHobbies(Map<String, Set<String>> hobbies) {
		this.hobbies = hobbies;
	}

	public Long[] getCategoryIds() {
		return categoryIds;
	}

	public void setCategoryIds(Long[] categoryIds) {
		this.categoryIds = categoryIds;
	}
	
	public String getFullName() {
		String fullName = "";
		if (StringUtils.isNotBlank(lastName)) {
			fullName += lastName + " ";
		}
		if (StringUtils.isNotBlank(middleName)) {
			fullName += middleName + " ";
		}
		if (StringUtils.isNotBlank(firstName)) {
			fullName += firstName;
		}
		fullName = StringUtils.stripToNull(fullName);
		return fullName;
	}

	public String getWebsite() {
		return website;
	}

	public void setWebsite(String website) {
		this.website = website;
	}

	@SynchronizeAttributeWithOther(direction = SynchronizeDirection.FROM, value = "userInfo")
	public void initUserInfoFromEntity(Object entity) {
		if (entity != null && entity instanceof UserInfo) {
			UserInfo userInfo = (UserInfo) entity;
			this.firstName = userInfo.getFirstName();
			this.lastName = userInfo.getLastName();
			this.middleName = userInfo.getMiddleName();
			this.male = userInfo.isMale();
			this.birthday = userInfo.getBirthday();
			this.mobilePhone = userInfo.getMobile();
			this.phone = userInfo.getPhone();
			this.mobilePhone = userInfo.getMobile();
			this.address = userInfo.getAddress();
			if (userInfo.getCity() != null) {
				this.city = userInfo.getCity().getCityName();
			}
			this.aboutMe = userInfo.getAboutMe();
			this.yahoo = userInfo.getYahoo();
			this.google = userInfo.getGoogle();
			this.skype = userInfo.getSkype();
			this.website = userInfo.getWebsite();
		}
	}

	@SynchronizeAttributeWithOther(direction = SynchronizeDirection.TO, value = "userInfo")
	public UserInfo copyUserInforToEntity() {
		// TODO: city
		UserInfo userInfo = new UserInfo();
		userInfo.setFirstName(this.firstName);
		userInfo.setMiddleName(this.middleName);
		userInfo.setLastName(this.lastName);
		userInfo.setMale(this.male);
		userInfo.setBirthday(this.birthday);
		userInfo.setPhone(this.phone);
		userInfo.setMobile(this.mobilePhone);
		userInfo.setAddress(this.address);
		userInfo.setYahoo(this.yahoo);
		userInfo.setGoogle(this.google);
		userInfo.setSkype(this.skype);
		userInfo.setAboutMe(this.aboutMe);
		return userInfo;
	}

	@SuppressWarnings("unchecked")
	@SynchronizeAttributeWithOther(direction = SynchronizeDirection.FROM, value = "userStatuses")
	public void initUserStatusFromEntity(Object entity) {
		if (entity != null && entity instanceof Set<?>) {
			Set<UserStatus> userStatuses = (Set<UserStatus>) entity;
			if(userStatuses.size() > 0){
				List<UserStatus> listStatuses = new ArrayList<UserStatus>(userStatuses);
				UserStatus userStatus = listStatuses.get(0);
				this.status = userStatus.getUserStatus();
			}
		}
	}

//	@SynchronizeAttributeWithOther(direction = SynchronizeDirection.TO, value = "userStatus")
//	public UserStatus copyUserStatusToEntity() {
//		UserStatus userStatus = new UserStatus();
//		userStatus.setUserStatus(this.status);
//		return userStatus;
//	}
	
	@SuppressWarnings("unchecked")
	@SynchronizeAttributeWithOther(direction = SynchronizeDirection.FROM, value = "hobbies")
	public void initUserHobbyFromEntity(Object entity) {
		if (entity != null && entity instanceof Set) {
			Set<Hobby> s = (Set<Hobby>) entity;
			if (s != null) {
				for (Hobby h : s) {
					String name = h.getName();
					String cat = h.getCategory();
					Set<String> list = this.hobbies.get(cat);
					if (list == null) {
						list = new HashSet<String>();
						this.hobbies.put(cat, list);
					}
					list.add(name);
				}
			}
		}
	}
	
	@SynchronizeAttributeWithOther(direction = SynchronizeDirection.TO, value = "hobbies")
	public Set<Hobby> copyUserHobbyToEntity() {
		return null;
	}
	
	@SuppressWarnings("unchecked")
	@SynchronizeAttributeWithOther(direction = SynchronizeDirection.FROM, value = "categories")
	public void initCategories(Object entity){
		if(entity != null){
			Set<Category> categories = (Set<Category>) entity;
			categoryIds = new Long[categories.size()];
			int index=0;
			for(Category category : categories){
				categoryIds[index] = category.getId();
				index++;
			}
		}
	}
	
}
